package com.tianheng.wanzhou.datacollecting.netty.cushaji;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tianheng.wanzhou.datacollecting.db.entity.MachineList;
import com.tianheng.wanzhou.datacollecting.db.service.IMachineListService;
import com.tianheng.wanzhou.datacollecting.util.CRC16Util;
import com.tianheng.wanzhou.datacollecting.util.StrUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.ReferenceCountUtil;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: tql
 * @Date: 2020/5/12 14:13
 * @Version 1.0
 */
@Component(value = "cushajiClient")
public class MyClient {

    @Autowired
    private ObjectFactory<ClientHandler> factory;
    @Autowired
    IMachineListService machineListService;


    private List<MachineList> machineList = new ArrayList<>();

    //netty组件
    EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
    Bootstrap bs = new Bootstrap();


    MyClient() {
        bs.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(factory.getObject())
                                .addLast("GatherDecoder", new GatherDecoder());
                    }
                });
    }

    @PostConstruct
    private void postConstruct() {
        QueryWrapper<MachineList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mac_type", 6).eq("status", 1);
        machineList = machineListService.list(queryWrapper);
    }

// 每10秒触发一次
    @Scheduled(cron = "0/10 * * * * ? ")
    public void sendMsg() {
        for (MachineList machine : this.machineList) {
            try{
                ChannelFuture cf = bs.connect(machine.getMacIp(), machine.getPort()).sync();
                String ip = machine.getMacIp().substring(12);
                int machineName =Integer.valueOf(ip).intValue()-10;
                String jt1 = String.valueOf(machineName);
                Integer it = Integer.valueOf(jt1);
                String result=Integer.toHexString(it);
                if (result.length()==1){
                    result = "0"+result;
                }
                String jt = result;
                //第1次
                ByteBuf byteBuf = Unpooled.buffer();
                byteBuf.retain();
                byte[] bytes0 = StrUtil.hexStr2Byte(jt+"03001E0074");
                byte[] msg0 = new byte[bytes0.length + 2];
                System.arraycopy(bytes0, 0, msg0, 0, bytes0.length);
                int check = CRC16Util.calcCrc16(msg0, 0, msg0.length-2);
                msg0[msg0.length -1] = (byte) ((check >> 8) & 0xff);
                msg0[msg0.length -2] = (byte) (check & 0xff);
                byteBuf.writeBytes(msg0);
                cf.channel().writeAndFlush(byteBuf);
                ReferenceCountUtil.release(byteBuf);
                Thread.sleep(1000);
                //第2次
                ByteBuf byteBuf1 = Unpooled.buffer();
                byteBuf1.retain();
                byte[] bytes1 = StrUtil.hexStr2Byte(jt+"0300CA004B");
                byte[] msg1 = new byte[bytes1.length + 2];
                System.arraycopy(bytes1, 0, msg1, 0, bytes1.length);
                int check1 = CRC16Util.calcCrc16(msg1, 0, msg1.length-2);
                msg1[msg1.length -1] = (byte) ((check1 >> 8) & 0xff);
                msg1[msg1.length -2] = (byte) (check1 & 0xff);
                byteBuf1.writeBytes(msg1);
                cf.channel().writeAndFlush(byteBuf1);
                ReferenceCountUtil.release(byteBuf1);
                Thread.sleep(1000);
                //第3次
                ByteBuf byteBuf2 = Unpooled.buffer();
                byteBuf2.retain();
                byte[] bytes2 = StrUtil.hexStr2Byte(jt+"030146005A");
                byte[] msg2 = new byte[bytes2.length + 2];
                System.arraycopy(bytes2, 0, msg2, 0, bytes2.length);
                int check2 = CRC16Util.calcCrc16(msg2, 0, msg2.length-2);
                msg2[msg2.length -1] = (byte) ((check2 >> 8) & 0xff);
                msg2[msg2.length -2] = (byte) (check2 & 0xff);
                byteBuf2.writeBytes(msg2);
                cf.channel().writeAndFlush(byteBuf2);
                ReferenceCountUtil.release(byteBuf2);
                Thread.sleep(1000);
                //第4次
                ByteBuf byteBuf3 = Unpooled.buffer();
                byteBuf3.retain();
                byte[] bytes3 = StrUtil.hexStr2Byte(jt+"0301CA003E");
                byte[] msg3 = new byte[bytes3.length + 2];
                System.arraycopy(bytes3, 0, msg3, 0, bytes3.length);
                int check3 = CRC16Util.calcCrc16(msg3, 0, msg3.length-2);
                msg3[msg3.length -1] = (byte) ((check3 >> 8) & 0xff);
                msg3[msg3.length -2] = (byte) (check3 & 0xff);
                byteBuf3.writeBytes(msg3);
                cf.channel().writeAndFlush(byteBuf3);
                ReferenceCountUtil.release(byteBuf3);
                Thread.sleep(1000);
                //第5次
                ByteBuf byteBuf4 = Unpooled.buffer();
                byteBuf4.retain();
                byte[] bytes4 = StrUtil.hexStr2Byte(jt+"0304600001");
                byte[] msg4 = new byte[bytes4.length + 2];
                System.arraycopy(bytes4, 0, msg4, 0, bytes4.length);
                int check4 = CRC16Util.calcCrc16(msg4, 0, msg4.length-2);
                msg4[msg4.length -1] = (byte) ((check4 >> 8) & 0xff);
                msg4[msg4.length -2] = (byte) (check4 & 0xff);
                byteBuf4.writeBytes(msg4);
                cf.channel().writeAndFlush(byteBuf4);
                ReferenceCountUtil.release(byteBuf4);
                Thread.sleep(1000);
                //第6次
                ByteBuf byteBuf5 = Unpooled.buffer();
                byteBuf5.retain();
                byte[] bytes5 = StrUtil.hexStr2Byte(jt+"0317700003");
                byte[] msg5 = new byte[bytes5.length + 2];
                System.arraycopy(bytes5, 0, msg5, 0, bytes5.length);
                int check5 = CRC16Util.calcCrc16(msg5, 0, msg5.length-2);
                msg5[msg5.length -1] = (byte) ((check5 >> 8) & 0xff);
                msg5[msg5.length -2] = (byte) (check5 & 0xff);
                byteBuf5.writeBytes(msg5);
                cf.channel().writeAndFlush(byteBuf5);
                ReferenceCountUtil.release(byteBuf5);
                Thread.sleep(1000);
                //第7次
                ByteBuf byteBuf6 = Unpooled.buffer();
                byteBuf6.retain();
                byte[] bytes6 = StrUtil.hexStr2Byte(jt+"031B580002");
                byte[] msg6 = new byte[bytes6.length + 2];
                System.arraycopy(bytes6, 0, msg6, 0, bytes6.length);
                int check6 = CRC16Util.calcCrc16(msg6, 0, msg6.length-2);
                msg6[msg6.length -1] = (byte) ((check6 >> 8) & 0xff);
                msg6[msg6.length -2] = (byte) (check6 & 0xff);
                byteBuf6.writeBytes(msg6);
                cf.channel().writeAndFlush(byteBuf6);
                ReferenceCountUtil.release(byteBuf6);
                Thread.sleep(1000);
            }catch (Exception e) {
                System.err.println(machine.getMacIp()+"连接失败" + e.getMessage());
            }







        }
    }

    //隔一小时更新一次设备列表
    @Scheduled(cron = "0 0 0/1 * * ?")
    public void updateMacList() {
        QueryWrapper<MachineList> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mac_type", 6).eq("status", 1);
        machineList = machineListService.list(queryWrapper);
    }
}
